class WebrtcConnection {
    peerconnection;
    
    constructor() {
        this.peerconnection = null;
    }

    // 创建和初始化 peerconnection
    async create(onCandidate, onTrack) {
        // 创建 RTC 连接
        this.peerconnection = new RTCPeerConnection({
            iceServers: [
                {
                    urls: 'stun:stun.l.google.com:19302' // Google的STUN服务器
                }
                // 可以添加更多 STUN 和 TURN 服务器
            ]
        });

        // ICE 候选事件：当媒体协商完成，TURN 服务器返回 ICE 候选时触发
        this.peerconnection.onicecandidate = (event) => {
            if (event.candidate) {
                onCandidate(event.candidate);
            } else {
                console.log('No more ICE candidates');
            }
        };

        // 远端媒体流事件：当远端流到达时触发
        this.peerconnection.ontrack = (event) => {
            onTrack(event.streams[0]);
        };

        // 一些日志事件
        // 连接状态变化事件
        this.peerconnection.oniceconnectionstatechange = () => {
            console.log('ICE Connection State Changed: ', this.peerconnection.iceConnectionState);
        };

        // 信令状态变化事件
        this.peerconnection.onsignalingstatechange = () => {
            console.log('Signaling State Changed: ', this.peerconnection.signalingState);
        };

        // 连接状态变化事件
        this.peerconnection.onconnectionstatechange = () => {
            console.log('Connection State Changed: ', this.peerconnection.connectionState);
        };

        // 连接建立事件
        this.peerconnection.onnegotiationneeded = () => {
            console.log('Negotiation Needed');
        };

        // 远端媒体流开始时触发
        this.peerconnection.onaddstream = (event) => {
            console.log('Remote stream added: ', event.stream);
        };

        // 错误事件
        this.peerconnection.onerror = (error) => {
            console.error('Peer connection error: ', error);
        };
    }

    // 创建本地 offer，并设置为本地描述
    async createAndSetLocalOffer() {
        try {
            const offer = await this.peerconnection.createOffer();
            await this.peerconnection.setLocalDescription(offer);
            return offer;
        } catch (error) {
            console.error('Error creating and setting local offer:', error);
        }
    }

    // 创建本地 answer，并设置为本地描述
    async createAndSetLocalAnswer() {
        try {
            const answer = await this.peerconnection.createAnswer();
            await this.peerconnection.setLocalDescription(answer);
            return answer;
        } catch (error) {
            console.error('Error creating and setting local answer:', error);
        }
    }

    // 设置远端描述（sdp）
    async setRemoteDescription(sdp) {
        try {
            await this.peerconnection.setRemoteDescription(new RTCSessionDescription(sdp));
        } catch (error) {
            console.error('Error setting remote description:', error);
        }
    }

    // 添加远端的 ICE 候选
    async setRemoteCandidate(candidate) {
        try {
            await this.peerconnection.addIceCandidate(candidate);
        } catch (error) {
            console.error('Error adding remote ICE candidate:', error);
        }
    }

    // 将本地流的轨道添加到 peerconnection 中
    addTrack(localStream) {
        try {
            localStream.getTracks().forEach((track) => {
                // 防止该函数被同一个流多次调用，导致添加重复轨道
                const isExistTrack = this.peerconnection.getSenders().find((sender) => sender.track === track)
                if (!isExistTrack) {
                    this.peerconnection.addTrack(track, localStream);
                }
            });
        } catch (error) {
            console.error('Error adding track to peerconnection:', error);
        }
    }

    // 暂停/恢复流的传输与生产
    // (enabled 是“阻止”流，stop() 是关闭流，从而“停止”流，如果使用 stop 需要重新调用getUserMedia 创建)
    toggleTrack(localStream, enabled) {
        // 停止所有轨道流的传输
        this.peerconnection.getSenders().forEach((sender) => {
            sender.track.enabled = enabled;
        })
        localStream.getTracks().forEach((track) => {
            track.enabled = enabled;
        });
    }

    // 暂停/恢复视频流的传输与生产
    //（senders 是控制RTC连接上的传输流的）
    toggleVideoTrack(localStream, enabled) {
        this.peerconnection.getSenders().forEach((sender) => {
            if (sender.track.kind === 'video') {
                sender.track.enabled = enabled;
            }
        })
        localStream.getVideoTracks().forEach((track) => {
            track.enabled = enabled;
        });
    }

    // 释放连接，清理资源
    close(localStream) {
        // 停止所有轨道的传输
        this.peerconnection.getSenders().forEach((sender) => {
            sender.track.stop();
        })
        localStream.getTracks().forEach((track) => {
            track.stop();
        })
        // 关闭 RTC 连接
        this.peerconnection.close();
        this.peerconnection = null;
        console.log('Peer connection closed');
    }

    // 一些工具方法
    // 将流注入到本地视频标签中
    setStreamToVideoElm(videoElm, stream) {
        if (videoElm) {
            // 如果有旧的流，先停止它
            const oldStream = videoElm.srcObject;
            if (oldStream) {
                oldStream.getTracks().forEach(track => {
                    track.stop()
                })
                videoElm.srcObject = null
            }
            videoElm.srcObject = stream
        }
    }

    // 使用新的视频流替换旧的视频流
    changeSendersVideoTrack(newLocalStream) {
        newLocalStream.getVideoTracks().forEach((track) => {
            this.peerconnection.getSenders().find((sender) => sender.track.kind === 'video').replaceTrack(track);
        })
    }
  
}

export default WebrtcConnection;
